package dog.weatherwallpaper.utils;

import java.io.File;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

import android.app.Application;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.text.TextUtils;
import android.widget.Toast;
import dog.weatherwallpaper.R;

public final class App extends Application {
	private static App instance;

	/**
	 * Do not instantiate this class. Public constructor required to avoid IllegalAccessException.
	 */
	public App() {
		instance = this;
	}

	public static Context context() {
		return instance;
	}

	/**
	 * Represents date in format yyMMdd. Modify it in AndroidManifest.xml before each deploy.
	 */
	public static int getManifestVersionCode() {
		try {
			return instance.getPackageManager().getPackageInfo(instance.getPackageName(), 0).versionCode;
		} catch (NameNotFoundException e) {
			App.sendMail(e);
		}
		return 0;
	}

	public static String getManifestVersionName() {
		try {
			return instance.getPackageManager().getPackageInfo(instance.getPackageName(), 0).versionName;
		} catch (NameNotFoundException e) {
			App.sendMail(e);
		}
		return "";
	}

	/**
	 * Shows floating message.
	 * 
	 * @param stringId
	 *            Resource id for the Text to show.
	 * @param duration
	 *            How long to display the message. Either Toast.LENGTH_SHORT or Toast.LENGTH_LONG.
	 */
	public static void toast(final int stringId, final int duration) {
		Toast.makeText(instance, instance.getString(stringId), duration).show();
	}

	/**
	 * Shows floating message.
	 * 
	 * @param string
	 *            Text to show.
	 * @param duration
	 *            How long to display the message. Either Toast.LENGTH_SHORT or Toast.LENGTH_LONG.
	 */
	public static void toast(final String string, final int duration) {
		Toast.makeText(instance, string, duration).show();
	}

	/**
	 * Checks whether the preferences contains a preference.
	 * 
	 * @param keyId
	 *            Resource id for the name of the preference to check.
	 * @return
	 *         Returns true if the preference exists in the preferences, otherwise false.
	 */
	public static boolean containsPreference(final int keyId) {
		final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(App.context());
		return sp.contains(instance.getString(keyId));
	}

	/**
	 * Returns value from SharedPreferences.<br>
	 * If the preference does not exist, returns false.
	 * 
	 * @param keyId
	 *            Resource id for the name of the preference to retrieve.
	 */
	public static boolean getBooleanPreference(final int keyId) {
		final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(App.context());
		return sp.getBoolean(instance.getString(keyId), false);
	}

	/**
	 * Returns value from SharedPreferences.<br>
	 * If the preference does not exist, returns default value.
	 * 
	 * @param keyId
	 *            Resource id for the name of the preference to retrieve.
	 * @param defaultId
	 *            Resource id for the value to return if this preference does not exist.
	 */
	public static int getIntPreference(final int keyId, final int defaultId) {
		final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(App.context());
		return Strings.tryParse(sp.getString(instance.getString(keyId), instance.getString(defaultId)));
	}

	/**
	 * Returns value from SharedPreferences.<br>
	 * If the preference does not exist, returns default value.
	 * 
	 * @param keyId
	 *            Resource id for the name of the preference to retrieve.
	 * @param defaultId
	 *            Resource id for the value to return if this preference does not exist.
	 */
	public static String getStringPreference(final int keyId, final int defaultId) {
		final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(App.context());
		return sp.getString(instance.getString(keyId), instance.getString(defaultId));
	}

	/**
	 * Returns value from SharedPreferences.<br>
	 * If the preference does not exist, returns the empty String.
	 * 
	 * @param keyId
	 *            Resource id for the name of the preference to retrieve.
	 */
	public static String getStringPreference(final int keyId) {
		final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(App.context());
		return sp.getString(instance.getString(keyId), "");
	}

	/**
	 * Saves the string to SharedPreferences.<br>
	 * Returns true if the new values were successfully written to persistent
	 * storage.
	 * 
	 * @param keyId
	 *            Resource id for the name of the preference to modify.
	 * @param value
	 *            The new value for the preference.
	 */
	public static boolean setStringPreference(final int keyId, final String value) {
		final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(App.context());
		return sp.edit().putString(App.context().getString(keyId), value).commit();
	}

	/**
	 * Starts activity from class. Creates an Intent with FLAG_ACTIVITY_NEW_TASK.
	 * 
	 * @param c
	 *            Class that extends from Activity.
	 */
	public static void startActivity(Class<?> c) {
		Intent i = new Intent(instance, c);
		i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		instance.startActivity(i);
	}

	/**
	 * Creates an intent to install an APK.
	 */
	public static Intent installationIntent() {
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setDataAndType(Uri.fromFile(new File(context().getFilesDir(), Internet.APK_FILE)), "application/vnd.android.package-archive");
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		return intent;
	}

	public static void sendMail(Exception e) {
		final String BR = "\n";
		String stackTrace = TextUtils.join(BR, e.getStackTrace());
		List<Serializable> tokens = Arrays.asList(e.getClass(), e.getMessage(), stackTrace);
		String text = TextUtils.join(BR, tokens);

		Intent send = new Intent(Intent.ACTION_SEND);
		send.setType("message/rfc822");
		send.putExtra(Intent.EXTRA_EMAIL, new String[] { "dariog88@gmail.com" });
		send.putExtra(Intent.EXTRA_SUBJECT, instance.getString(R.string.crash_report));
		send.putExtra(Intent.EXTRA_TEXT, text);
		Intent chooser = Intent.createChooser(send, instance.getString(R.string.crash_report_send_mail));
		chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context().startActivity(chooser);
	}

	public static void createNotification(int icon, String title, String text, Class<?> cls) {
		NotificationCompat.Builder builder = new NotificationCompat.Builder(instance).setSmallIcon(icon)
				.setContentTitle(title).setContentText(text).setAutoCancel(true);
		Intent resultIntent = new Intent(instance, cls);
		TaskStackBuilder stackBuilder = TaskStackBuilder.create(instance);
		stackBuilder.addParentStack(cls);
		stackBuilder.addNextIntent(resultIntent);
		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_CANCEL_CURRENT);
		builder.setContentIntent(resultPendingIntent);
		NotificationManager manager = (NotificationManager) instance.getSystemService(Context.NOTIFICATION_SERVICE);
		manager.notify(0, builder.build());
	}

	public static int getIconId(String iconName) {
		return instance.getResources().getIdentifier(iconName, "drawable", instance.getPackageName());
	}

	public static ConnectivityManager getConnectivityManager() {
		return (ConnectivityManager) instance.getSystemService(Context.CONNECTIVITY_SERVICE);
	}
}